home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Unix / cvs-960311 / info / cvs.info-2 (.txt) < prev    next >
GNU Info File  |  1996-01-24  |  50KB  |  1,015 lines

  1. This is Info file cvs.info, produced by Makeinfo-1.64 from the input
  2. file ./cvs.texinfo.
  3.    Copyright (C) 1992, 1993 Signum Support AB Copyright (C) 1993, 1994
  4. Free Software Foundation, Inc.
  5.    Permission is granted to make and distribute verbatim copies of this
  6. manual provided the copyright notice and this permission notice are
  7. preserved on all copies.
  8.    Permission is granted to copy and distribute modified versions of
  9. this manual under the conditions for verbatim copying, provided also
  10. that the section entitled "GNU General Public License" is included
  11. exactly as in the original, and provided that the entire resulting
  12. derived work is distributed under the terms of a permission notice
  13. identical to this one.
  14.    Permission is granted to copy and distribute translations of this
  15. manual into another language, under the above conditions for modified
  16. versions, except that the section entitled "GNU General Public License"
  17. and this permission notice may be included in translations approved by
  18. the Free Software Foundation instead of in the original English.
  19. File: cvs.info,  Node: Updating a file,  Next: Conflicts example,  Prev: File status,  Up: Multiple developers
  20. Bringing a file up to date
  21. ==========================
  22.    When you want to update or merge a file, use the `update' command.
  23. For files that are not up to date this is roughly equivalent to a
  24. `checkout' command: the newest revision of the file is extracted from
  25. the repository and put in your working copy of the module.
  26.    Your modifications to a file are never lost when you use `update'.
  27. If no newer revision exists, running `update' has no effect.  If you
  28. have edited the file, and a newer revision is available, CVS will merge
  29. all changes into your working copy.
  30.    For instance, imagine that you checked out revision 1.4 and started
  31. editing it.  In the meantime someone else committed revision 1.5, and
  32. shortly after that revision 1.6.  If you run `update' on the file now,
  33. CVS will incorporate all changes between revision 1.4 and 1.6 into your
  34. file.
  35.    If any of the changes between 1.4 and 1.6 were made too close to any
  36. of the changes you have made, an "overlap" occurs.  In such cases a
  37. warning is printed, and the resulting file includes both versions of
  38. the lines that overlap, delimited by special markers.  *Note update::,
  39. for a complete description of the `update' command.
  40. File: cvs.info,  Node: Conflicts example,  Next: Informing others,  Prev: Updating a file,  Up: Multiple developers
  41. Conflicts example
  42. =================
  43.    Suppose revision 1.4 of `driver.c' contains this:
  44.      #include <stdio.h>
  45.      
  46.      void main()
  47.      {
  48.          parse();
  49.          if (nerr == 0)
  50.              gencode();
  51.          else
  52.              fprintf(stderr, "No code generated.\n");
  53.          exit(nerr == 0 ? 0 : 1);
  54.      }
  55. Revision 1.6 of `driver.c' contains this:
  56.      #include <stdio.h>
  57.      
  58.      int main(int argc,
  59.               char **argv)
  60.      {
  61.          parse();
  62.          if (argc != 1)
  63.          {
  64.              fprintf(stderr, "tc: No args expected.\n");
  65.              exit(1);
  66.          }
  67.          if (nerr == 0)
  68.              gencode();
  69.          else
  70.              fprintf(stderr, "No code generated.\n");
  71.          exit(!!nerr);
  72.      }
  73. Your working copy of `driver.c', based on revision 1.4, contains this
  74. before you run `cvs update':
  75.      #include <stdlib.h>
  76.      #include <stdio.h>
  77.      
  78.      void main()
  79.      {
  80.          init_scanner();
  81.          parse();
  82.          if (nerr == 0)
  83.              gencode();
  84.          else
  85.              fprintf(stderr, "No code generated.\n");
  86.          exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  87.      }
  88. You run `cvs update':
  89.      $ cvs update driver.c
  90.      RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v
  91.      retrieving revision 1.4
  92.      retrieving revision 1.6
  93.      Merging differences between 1.4 and 1.6 into driver.c
  94.      rcsmerge warning: overlaps during merge
  95.      cvs update: conflicts found in driver.c
  96.      C driver.c
  97. CVS tells you that there were some conflicts.  Your original working
  98. file is saved unmodified in `.#driver.c.1.4'.  The new version of
  99. `driver.c' contains this:
  100.      #include <stdlib.h>
  101.      #include <stdio.h>
  102.      
  103.      int main(int argc,
  104.               char **argv)
  105.      {
  106.          init_scanner();
  107.          parse();
  108.          if (argc != 1)
  109.          {
  110.              fprintf(stderr, "tc: No args expected.\n");
  111.              exit(1);
  112.          }
  113.          if (nerr == 0)
  114.              gencode();
  115.          else
  116.              fprintf(stderr, "No code generated.\n");
  117.      <<<<<<< driver.c
  118.          exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  119.      =======
  120.          exit(!!nerr);
  121.      >>>>>>> 1.6
  122.      }
  123. Note how all non-overlapping modifications are incorporated in your
  124. working copy, and that the overlapping section is clearly marked with
  125. `<<<<<<<', `=======' and `>>>>>>>'.
  126.    You resolve the conflict by editing the file, removing the markers
  127. and the erroneous line.  Suppose you end up with this file:
  128.      #include <stdlib.h>
  129.      #include <stdio.h>
  130.      
  131.      int main(int argc,
  132.               char **argv)
  133.      {
  134.          init_scanner();
  135.          parse();
  136.          if (argc != 1)
  137.          {
  138.              fprintf(stderr, "tc: No args expected.\n");
  139.              exit(1);
  140.          }
  141.          if (nerr == 0)
  142.              gencode();
  143.          else
  144.              fprintf(stderr, "No code generated.\n");
  145.          exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
  146.      }
  147. You can now go ahead and commit this as revision 1.7.
  148.      $ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c
  149.      Checking in driver.c;
  150.      /usr/local/cvsroot/yoyodyne/tc/driver.c,v  <--  driver.c
  151.      new revision: 1.7; previous revision: 1.6
  152.      done
  153.    If you use release 1.04 or later of pcl-cvs (a GNU Emacs front-end
  154. for CVS) you can use an Emacs package called emerge to help you resolve
  155. conflicts.  See the documentation for pcl-cvs.
  156. File: cvs.info,  Node: Informing others,  Next: Concurrency,  Prev: Conflicts example,  Up: Multiple developers
  157. Informing others about commits
  158. ==============================
  159.    It is often useful to inform others when you commit a new revision
  160. of a file.  The `-i' option of the `modules' file, or the `loginfo'
  161. file, can be used to automate this process.  *Note modules::.  *Note
  162. loginfo::.  You can use these features of CVS to, for instance,
  163. instruct CVS to mail a message to all developers, or post a message to
  164. a local newsgroup.
  165. File: cvs.info,  Node: Concurrency,  Next: Watches,  Prev: Informing others,  Up: Multiple developers
  166. Several developers simultaneously attempting to run CVS
  167. =======================================================
  168.    If several developers try to run CVS at the same time, one may get
  169. the following message:
  170.      [11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo
  171.    CVS will try again every 30 seconds, and either continue with the
  172. operation or print the message again, if it still needs to wait.  If a
  173. lock seems to stick around for an undue amount of time, find the person
  174. holding the lock and ask them about the cvs command they are running.
  175. If they aren't running a cvs command, look for and remove files
  176. starting with `#cvs.tfl', `#cvs.rfl', or `#cvs.wfl' from the repository.
  177.    Note that these locks are to protect CVS's internal data structures
  178. and have no relationship to the word "lock" in the sense used by RCS-a
  179. way to prevent other developers from working on a particular file.
  180.    Any number of people can be reading from a given repository at a
  181. time; only when someone is writing do the locks prevent other people
  182. from reading or writing.
  183.    One might hope for the following property
  184.      If someone commits some changes in one cvs command,
  185.      then an update by someone else will either get all the
  186.      changes, or none of them.
  187.    but CVS does *not* have this property.  For example, given the files
  188.      a/one.c
  189.      a/two.c
  190.      b/three.c
  191.      b/four.c
  192.    if someone runs
  193.      cvs ci a/two.c b/three.c
  194.    and someone else runs `cvs update' at the same time, the person
  195. running `update' might get only the change to `b/three.c' and not the
  196. change to `a/two.c'.
  197. File: cvs.info,  Node: Watches,  Prev: Concurrency,  Up: Multiple developers
  198. Mechanisms to track who is editing files
  199. ========================================
  200.    For many groups, use of CVS in its default mode is perfectly
  201. satisfactory.  Users may sometimes go to check in a modification only
  202. to find that another modification has intervened, but they deal with it
  203. and proceed with their check in.  Other groups prefer to be able to
  204. know who is editing what files, so that if two people try to edit the
  205. same file they can choose to talk about who is doing what when rather
  206. than be surprised at check in time.  The features in this section allow
  207. such coordination, while retaining the ability of two developers to
  208. edit the same file at the same time.
  209.    For maximum benefit developers should use `cvs edit' (not `chmod')
  210. to make files read-write to edit them, and `cvs release' (not `rm') to
  211. discard a working directory which is no longer in use, but CVS is not
  212. able to enforce this behavior.
  213. * Menu:
  214. * Setting a watch::             Telling CVS to watch certain files
  215. * Getting Notified::            Telling CVS to notify you
  216. * Editing files::               How to edit a file which is being watched
  217. * Watch information::           Information about who is watching and editing
  218. * Watches Compatibility::       Watches interact poorly with CVS 1.6 or earlier
  219. File: cvs.info,  Node: Setting a watch,  Next: Getting Notified,  Up: Watches
  220. Telling CVS to watch certain files
  221. ----------------------------------
  222.    To enable the watch features, you first specify that certain files
  223. are to be watched.
  224.  - Command: cvs watch on [`-l'] FILES ...
  225.      Specify that developers should run `cvs edit' before editing
  226.      FILES.  CVS will create working copies of FILES read-only, to
  227.      remind developers to run the `cvs edit' command before working on
  228.      them.
  229.      If FILES includes the name of a directory, CVS arranges to watch
  230.      all files added to the corresponding repository directory, and
  231.      sets a default for files added in the future; this allows the user
  232.      to set notification policies on a per-directory basis.  The
  233.      contents of the directory are processed recursively, unless the
  234.      `-l' option is given.
  235.      If FILES is omitted, it defaults to the current directory.
  236.  - Command: cvs watch off [`-l'] FILES ...
  237.      Do not provide notification about work on FILES.  CVS will create
  238.      working copies of FILES read-write.
  239.      The FILES and `-l' arguments are processed as for `cvs watch on'.
  240. File: cvs.info,  Node: Getting Notified,  Next: Editing files,  Prev: Setting a watch,  Up: Watches
  241. Telling CVS to notify you
  242. -------------------------
  243.    You can tell CVS that you want to receive notifications about
  244. various actions taken on a file.  You can do this without using `cvs
  245. watch on' for the file, but generally you will want to use `cvs watch
  246. on', so that developers use the `cvs edit' command.
  247.  - Command: cvs watch add [`-a' ACTION] [`-l'] FILES ...
  248.      Add the current user to the list of people to receive notification
  249.      of work done on FILES.
  250.      The `-a' option specifies what kinds of events CVS should notify
  251.      the user about.  ACTION is one of the following:
  252.     `edit'
  253.           Another user has applied the `cvs edit' command (described
  254.           below) to a file.
  255.     `unedit'
  256.           Another user has applied the `cvs unedit' command (described
  257.           below) or the `cvs release' command to a file, or has deleted
  258.           the file and allowed `cvs update' to recreate it.
  259.     `commit'
  260.           Another user has committed changes to a file.
  261.     `all'
  262.           All of the above.
  263.     `none'
  264.           None of the above.  (This is useful with `cvs edit',
  265.           described below.)
  266.      The `-a' option may appear more than once, or not at all.  If
  267.      omitted, the action defaults to `all'.
  268.      The FILES and `-l' option are processed as for the `cvs watch'
  269.      commands.
  270.  - Command: cvs watch remove [`-a' ACTION] [`-l'] FILES ...
  271.      Remove a notification request established using `cvs watch add';
  272.      the arguments are the same.  If the `-a' option is present, only
  273.      watches for the specified actions are removed.
  274.    When the conditions exist for notification, CVS calls the `notify'
  275. administrative file, passing it the user to receive the notification
  276. and the user who is taking the action which results in notification.
  277. Normally `notify' will just send an email message.
  278.    Note that if you set this up in the straightforward way, users
  279. receive notifications on the server machine.  One could of course write
  280. a `notify' script which directed notifications elsewhere, but to make
  281. this easy, CVS allows you to associate a notification address for each
  282. user.  To do so create a file `users' in `CVSROOT' with a line for each
  283. user in the format USER:VALUE.  Then instead of passing the name of the
  284. user to be notified to `notify', CVS will pass the VALUE (normally an
  285. email address on some other machine).
  286. File: cvs.info,  Node: Editing files,  Next: Watch information,  Prev: Getting Notified,  Up: Watches
  287. How to edit a file which is being watched
  288. -----------------------------------------
  289.    Since a file which is being watched is checked out read-only, you
  290. cannot simply edit it.  To make it read-write, and inform others that
  291. you are planning to edit it, use the `cvs edit' command.
  292.  - Command: cvs edit [OPTIONS] FILES ...
  293.      Prepare to edit the working files FILES.  CVS makes the FILES
  294.      read-write, and notifies users who have requested `edit'
  295.      notification for any of FILES.
  296.      The `cvs edit' command accepts the same OPTIONS as the `cvs watch
  297.      add' command, and establishes a temporary watch for the user on
  298.      FILES; CVS will remove the watch when FILES are `unedit'ed or
  299.      `commit'ted.  If the user does not wish to receive notifications,
  300.      she should specify `-a none'.
  301.      The FILES and `-l' option are processed as for the `cvs watch'
  302.      commands.
  303.    Normally when you are done with a set of changes, you use the `cvs
  304. commit' command, which checks in your changes and returns the watched
  305. files to their usual read-only state.  But if you instead decide to
  306. abandon your changes, or not to make any changes, you can use the `cvs
  307. unedit' command.
  308.  - Command: cvs unedit [`-l'] FILES ...
  309.      Abandon work on the working files FILES, and revert them to the
  310.      repository versions on which they are based.  CVS makes those
  311.      FILES read-only for which users have requested notification using
  312.      `cvs watch on'.  CVS notifies users who have requested `unedit'
  313.      notification for any of FILES.
  314.      The FILES and `-l' option are processed as for the `cvs watch'
  315.      commands.
  316.    When using client/server CVS, you can use the `cvs edit' and `cvs
  317. unedit' commands even if CVS is unable to succesfully communicate with
  318. the server; the notifications will be sent upon the next successful CVS
  319. command.
  320. File: cvs.info,  Node: Watch information,  Next: Watches Compatibility,  Prev: Editing files,  Up: Watches
  321. Information about who is watching and editing
  322. ---------------------------------------------
  323.  - Command: cvs watchers [`-l'] FILES ...
  324.      List the users currently watching changes to FILES.  The report
  325.      includes the files being watched, and the mail address of each
  326.      watcher.
  327.      The FILES and `-l' arguments are processed as for the `cvs watch'
  328.      commands.
  329.  - Command: cvs editors [`-l'] FILES ...
  330.      List the users currently working on FILES.  The report includes
  331.      the mail address of each user, the time when the user began
  332.      working with the file, and the host and path of the working
  333.      directory containing the file.
  334.      The FILES and `-l' arguments are processed as for the `cvs watch'
  335.      commands.
  336. File: cvs.info,  Node: Watches Compatibility,  Prev: Watch information,  Up: Watches
  337. Using watches with old versions of CVS
  338. --------------------------------------
  339.    If you use the watch features on a repository, it creates `CVS'
  340. directories in the repository and stores the information about watches
  341. in that directory.  If you attempt to use CVS 1.6 or earlier with the
  342. repository, you get an error message such as
  343.      cvs update: cannot open CVS/Entries for reading: No such file or directory
  344.    and your operation will likely be aborted.  To use the watch
  345. features, you must upgrade all copies of CVS which use that repository
  346. in local or server mode.  If you cannot upgrade, use the `watch off' and
  347. `watch remove' commands to remove all watches, and that will restore
  348. the repository to a state which CVS 1.6 can cope with.
  349. File: cvs.info,  Node: Branches,  Next: Merging,  Prev: Multiple developers,  Up: Top
  350. Branches
  351. ********
  352.    So far, all revisions shown in this manual have been on the "main
  353. trunk" of the revision tree, i.e., all revision numbers have been of
  354. the form X.Y.  One useful feature, especially when maintaining several
  355. releases of a software product at once, is the ability to make branches
  356. on the revision tree.  "Tags", symbolic names for revisions, will also
  357. be introduced in this chapter.
  358. * Menu:
  359. * Tags::                        Tags-Symbolic revisions
  360. * Branches motivation::         What branches are good for
  361. * Creating a branch::           Creating a branch
  362. * Sticky tags::                 Sticky tags
  363. File: cvs.info,  Node: Tags,  Next: Branches motivation,  Up: Branches
  364. Tags-Symbolic revisions
  365. =======================
  366.    The revision numbers live a life of their own.  They need not have
  367. anything at all to do with the release numbers of your software
  368. product.  Depending on how you use CVS the revision numbers might
  369. change several times between two releases.  As an example, some of the
  370. source files that make up RCS 5.6 have the following revision numbers:
  371.      ci.c            5.21
  372.      co.c            5.9
  373.      ident.c         5.3
  374.      rcs.c           5.12
  375.      rcsbase.h       5.11
  376.      rcsdiff.c       5.10
  377.      rcsedit.c       5.11
  378.      rcsfcmp.c       5.9
  379.      rcsgen.c        5.10
  380.      rcslex.c        5.11
  381.      rcsmap.c        5.2
  382.      rcsutil.c       5.10
  383.    You can use the `tag' command to give a symbolic name to a certain
  384. revision of a file.  You can use the `-v' flag to the `status' command
  385. to see all tags that a file has, and which revision numbers they
  386. represent.
  387.    The following example shows how you can add a tag to a file.  The
  388. commands must be issued inside your working copy of the module.  That
  389. is, you should issue the command in the directory where `backend.c'
  390. resides.
  391.      $ cvs tag release-0-4 backend.c
  392.      T backend.c
  393.      $ cvs status -v backend.c
  394.      ===================================================================
  395.      File: backend.c         Status: Up-to-date
  396.      
  397.          Version:            1.4     Tue Dec  1 14:39:01 1992
  398.          RCS Version:        1.4     /usr/local/cvsroot/yoyodyne/tc/backend.c,v
  399.          Sticky Tag:         (none)
  400.          Sticky Date:        (none)
  401.          Sticky Options:     (none)
  402.      
  403.          Existing Tags:
  404.              release-0-4                     (revision: 1.4)
  405.    There is seldom reason to tag a file in isolation.  A more common
  406. use is to tag all the files that constitute a module with the same tag
  407. at strategic points in the development life-cycle, such as when a
  408. release is made.
  409.      $ cvs tag release-1-0 .
  410.      cvs tag: Tagging .
  411.      T Makefile
  412.      T backend.c
  413.      T driver.c
  414.      T frontend.c
  415.      T parser.c
  416.    (When you give CVS a directory as argument, it generally applies the
  417. operation to all the files in that directory, and (recursively), to any
  418. subdirectories that it may contain.  *Note Recursive behavior::.)
  419.    The `checkout' command has a flag, `-r', that lets you check out a
  420. certain revision of a module.  This flag makes it easy to retrieve the
  421. sources that make up release 1.0 of the module `tc' at any time in the
  422. future:
  423.      $ cvs checkout -r release-1-0 tc
  424. This is useful, for instance, if someone claims that there is a bug in
  425. that release, but you cannot find the bug in the current working copy.
  426.    You can also check out a module as it was at any given date.  *Note
  427. checkout options::.
  428.    When you tag more than one file with the same tag you can think
  429. about the tag as "a curve drawn through a matrix of filename vs.
  430. revision number."  Say we have 5 files with the following revisions:
  431.              file1   file2   file3   file4   file5
  432.      
  433.              1.1     1.1     1.1     1.1  /--1.1*      <-*-  TAG
  434.              1.2*-   1.2     1.2    -1.2*-
  435.              1.3  \- 1.3*-   1.3   / 1.3
  436.              1.4          \  1.4  /  1.4
  437.                            \-1.5*-   1.5
  438.                              1.6
  439.    At some time in the past, the `*' versions were tagged.  You can
  440. think of the tag as a handle attached to the curve drawn through the
  441. tagged revisions.  When you pull on the handle, you get all the tagged
  442. revisions.  Another way to look at it is that you "sight" through a set
  443. of revisions that is "flat" along the tagged revisions, like this:
  444.              file1   file2   file3   file4   file5
  445.      
  446.                              1.1
  447.                              1.2
  448.                      1.1     1.3                       _
  449.              1.1     1.2     1.4     1.1              /
  450.              1.2*----1.3*----1.5*----1.2*----1.1     (--- <--- Look here
  451.              1.3             1.6     1.3              \_
  452.              1.4                     1.4
  453.                                      1.5
  454. File: cvs.info,  Node: Branches motivation,  Next: Creating a branch,  Prev: Tags,  Up: Branches
  455. What branches are good for
  456. ==========================
  457.    Suppose that release 1.0 of tc has been made.  You are continuing to
  458. develop tc, planning to create release 1.1 in a couple of months.
  459. After a while your customers start to complain about a fatal bug.  You
  460. check out release 1.0 (*note Tags::.) and find the bug (which turns out
  461. to have a trivial fix).  However, the current revision of the sources
  462. are in a state of flux and are not expected to be stable for at least
  463. another month.  There is no way to make a bugfix release based on the
  464. newest sources.
  465.    The thing to do in a situation like this is to create a "branch" on
  466. the revision trees for all the files that make up release 1.0 of tc.
  467. You can then make modifications to the branch without disturbing the
  468. main trunk.  When the modifications are finished you can select to
  469. either incorporate them on the main trunk, or leave them on the branch.
  470. File: cvs.info,  Node: Creating a branch,  Next: Sticky tags,  Prev: Branches motivation,  Up: Branches
  471. Creating a branch
  472. =================
  473.    The `rtag' command can be used to create a branch.  The `rtag'
  474. command is much like `tag', but it does not require that you have a
  475. working copy of the module.  *Note rtag::.  (You can also use the `tag'
  476. command; *note tag::.).
  477.      $ cvs rtag -b -r release-1-0 release-1-0-patches tc
  478.    The `-b' flag makes `rtag' create a branch (rather than just a
  479. symbolic revision name).  `-r release-1-0' says that this branch should
  480. be rooted at the node (in the revision tree) that corresponds to the tag
  481. `release-1-0'.  Note that the numeric revision number that matches
  482. `release-1-0' will probably be different from file to file.  The name
  483. of the new branch is `release-1-0-patches', and the module affected is
  484. `tc'.
  485.    To fix the problem in release 1.0, you need a working copy of the
  486. branch you just created.
  487.      $ cvs checkout -r release-1-0-patches tc
  488.      $ cvs status -v driver.c backend.c
  489.      ===================================================================
  490.      File: driver.c          Status: Up-to-date
  491.      
  492.          Version:            1.7     Sat Dec  5 18:25:54 1992
  493.          RCS Version:        1.7     /usr/local/cvsroot/yoyodyne/tc/driver.c,v
  494.          Sticky Tag:         release-1-0-patches (branch: 1.7.2)
  495.          Sticky Date:        (none)
  496.          Sticky Options:     (none)
  497.      
  498.          Existing Tags:
  499.              release-1-0-patches             (branch: 1.7.2)
  500.              release-1-0                     (revision: 1.7)
  501.      
  502.      ===================================================================
  503.      File: backend.c         Status: Up-to-date
  504.      
  505.          Version:            1.4     Tue Dec  1 14:39:01 1992
  506.          RCS Version:        1.4     /usr/local/cvsroot/yoyodyne/tc/backend.c,v
  507.          Sticky Tag:         release-1-0-patches (branch: 1.4.2)
  508.          Sticky Date:        (none)
  509.          Sticky Options:     (none)
  510.      
  511.          Existing Tags:
  512.              release-1-0-patches             (branch: 1.4.2)
  513.              release-1-0                     (revision: 1.4)
  514.              release-0-4                     (revision: 1.4)
  515.    As the output from the `status' command shows the branch number is
  516. created by adding a digit at the tail of the revision number it is
  517. based on.  (If `release-1-0' corresponds to revision 1.4, the branch's
  518. revision number will be 1.4.2.  For obscure reasons CVS always gives
  519. branches even numbers, starting at 2.  *Note Revision numbers::).
  520. File: cvs.info,  Node: Sticky tags,  Prev: Creating a branch,  Up: Branches
  521. Sticky tags
  522. ===========
  523.    The `-r release-1-0-patches' flag that was given to `checkout' is
  524. "sticky", that is, it will apply to subsequent commands in this
  525. directory.  If you commit any modifications, they are committed on the
  526. branch.  You can later merge the modifications into the main trunk.
  527. *Note Merging::.
  528.      $ vi driver.c   # Fix the bugs
  529.      $ cvs commit -m "Fixed initialization bug" driver.c
  530.      Checking in driver.c;
  531.      /usr/local/cvsroot/yoyodyne/tc/driver.c,v  <--  driver.c
  532.      new revision: 1.7.2.1; previous revision: 1.7
  533.      done
  534.      $ cvs status -v driver.c
  535.      ===================================================================
  536.      File: driver.c          Status: Up-to-date
  537.      
  538.          Version:            1.7.2.1 Sat Dec  5 19:35:03 1992
  539.          RCS Version:        1.7.2.1 /usr/local/cvsroot/yoyodyne/tc/driver.c,v
  540.          Sticky Tag:         release-1-0-patches (branch: 1.7.2)
  541.          Sticky Date:        (none)
  542.          Sticky Options:     (none)
  543.      
  544.          Existing Tags:
  545.              release-1-0-patches             (branch: 1.7.2)
  546.              release-1-0                     (revision: 1.7)
  547.    The sticky tags will remain on your working files until you delete
  548. them with `cvs update -A'.  *Note update::.
  549.    Sticky tags are not just for branches.  If you check out a certain
  550. revision (such as 1.4) it will also become sticky.  Subsequent `cvs
  551. update' will not retrieve the latest revision until you reset the tag
  552. with `cvs update -A'.
  553.    See the descriptions in Appendix A for more information about sticky
  554. tags.  Dates and some other options can also be sticky.  Again, see
  555. Appendix A for details.
  556. File: cvs.info,  Node: Merging,  Next: Recursive behavior,  Prev: Branches,  Up: Top
  557. Merging
  558. *******
  559.    You can include the changes made between any two revisions into your
  560. working copy, by "merging".  You can then commit that revision, and
  561. thus effectively copy the changes onto another branch.
  562. * Menu:
  563. * Merging a branch::            Merging an entire branch
  564. * Merging more than once::      Merging from a branch several times
  565. * Merging two revisions::       Merging differences between two revisions
  566. File: cvs.info,  Node: Merging a branch,  Next: Merging more than once,  Up: Merging
  567. Merging an entire branch
  568. ========================
  569.    You can merge changes made on a branch into your working copy by
  570. giving the `-j BRANCH' flag to the `update' command.  With one `-j
  571. BRANCH' option it merges the changes made between the point where the
  572. branch forked and newest revision on that branch (into your working
  573. copy).
  574.    The `-j' stands for "join".
  575.    Consider this revision tree:
  576.      +-----+    +-----+    +-----+    +-----+
  577.      ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !      <- The main trunk
  578.      +-----+    +-----+    +-----+    +-----+
  579.                      !
  580.                      !
  581.                      !   +---------+    +---------+
  582.      Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
  583.                          +---------+    +---------+
  584. The branch 1.2.2 has been given the tag (symbolic name) `R1fix'.  The
  585. following example assumes that the module `mod' contains only one file,
  586. `m.c'.
  587.      $ cvs checkout mod               # Retrieve the latest revision, 1.4
  588.      
  589.      $ cvs update -j R1fix m.c        # Merge all changes made on the branch,
  590.                                       # i.e. the changes between revision 1.2
  591.                                       # and 1.2.2.2, into your working copy
  592.                                       # of the file.
  593.      
  594.      $ cvs commit -m "Included R1fix" # Create revision 1.5.
  595.    A conflict can result from a merge operation.  If that happens, you
  596. should resolve it before committing the new revision.  *Note Conflicts
  597. example::.
  598.    The `checkout' command also supports the `-j BRANCH' flag.  The same
  599. effect as above could be achieved with this:
  600.      $ cvs checkout -j R1fix mod
  601.      $ cvs commit -m "Included R1fix"
  602. File: cvs.info,  Node: Merging more than once,  Next: Merging two revisions,  Prev: Merging a branch,  Up: Merging
  603. Merging from a branch several times
  604. ===================================
  605.    Continuing our example, the revision tree now looks like this:
  606.      +-----+    +-----+    +-----+    +-----+    +-----+
  607.      ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !      <- The main trunk
  608.      +-----+    +-----+    +-----+    +-----+    +-----+
  609.                      !                           *
  610.                      !                          *
  611.                      !   +---------+    +---------+
  612.      Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
  613.                          +---------+    +---------+
  614.    where the starred line represents the merge from the `R1fix' branch
  615. to the main trunk, as just discussed.
  616.    Now suppose that development continues on the `R1fix' branch:
  617.      +-----+    +-----+    +-----+    +-----+    +-----+
  618.      ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !      <- The main trunk
  619.      +-----+    +-----+    +-----+    +-----+    +-----+
  620.                      !                           *
  621.                      !                          *
  622.                      !   +---------+    +---------+    +---------+
  623.      Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
  624.                          +---------+    +---------+    +---------+
  625.    and then you want to merge those new changes onto the main trunk.
  626. If you just use the `cvs update -j R1fix m.c' command again, CVS will
  627. attempt to merge again the changes which you have already merged, which
  628. can have undesirable side effects.
  629.    So instead you need to specify that you only want to merge the
  630. changes on the branch which have not yet been merged into the trunk.
  631. To do that you specify two `-j' options, and CVS merges the changes from
  632. the first revision to the second revision.  For example, in this case
  633. the simplest way would be
  634.      cvs update -j 1.2.2.2 -j R1fix m.c    # Merge changes from 1.2.2.2 to the
  635.                                            # head of the R1fix branch
  636.    The problem with this is that you need to specify the 1.2.2.2
  637. revision manually.  A slightly better approach might be to use the date
  638. the last merge was done:
  639.      cvs update -j R1fix:yesterday -j R1fix m.c
  640.    Better yet, tag the R1fix branch after every merge into the trunk,
  641. and then use that tag for subsequent merges:
  642.      cvs update -j merged_from_R1fix_to_trunk -j R1fix m.c
  643. File: cvs.info,  Node: Merging two revisions,  Prev: Merging more than once,  Up: Merging
  644. Merging differences between any two revisions
  645. =============================================
  646.    With two `-j REVISION' flags, the `update' (and `checkout') command
  647. can merge the differences between any two revisions into your working
  648. file.
  649.      $ cvs update -j 1.5 -j 1.3 backend.c
  650. will *remove* all changes made between revision 1.3 and 1.5.  Note the
  651. order of the revisions!
  652.    If you try to use this option when operating on multiple files,
  653. remember that the numeric revisions will probably be very different
  654. between the various files that make up a module.  You almost always use
  655. symbolic tags rather than revision numbers when operating on multiple
  656. files.
  657. File: cvs.info,  Node: Recursive behavior,  Next: Adding files,  Prev: Merging,  Up: Top
  658. Recursive behavior
  659. ******************
  660.    Almost all of the subcommands of CVS work recursively when you
  661. specify a directory as an argument.  For instance, consider this
  662. directory structure:
  663.            `$HOME'
  664.              |
  665.              +--tc
  666.              |   |
  667.                  +--CVS
  668.                  |      (internal CVS files)
  669.                  +--Makefile
  670.                  +--backend.c
  671.                  +--driver.c
  672.                  +--frontend.c
  673.                  +--parser.c
  674.                  +--man
  675.                  |    |
  676.                  |    +--CVS
  677.                  |    |  (internal CVS files)
  678.                  |    +--tc.1
  679.                  |
  680.                  +--testing
  681.                       |
  682.                       +--CVS
  683.                       |  (internal CVS files)
  684.                       +--testpgm.t
  685.                       +--test2.t
  686. If `tc' is the current working directory, the following is true:
  687.    * `cvs update testing' is equivalent to `cvs update
  688.      testing/testpgm.t testing/test2.t'
  689.    * `cvs update testing man' updates all files in the subdirectories
  690.    * `cvs update .' or just `cvs update' updates all files in the `tc'
  691.      module
  692.    If no arguments are given to `update' it will update all files in
  693. the current working directory and all its subdirectories.  In other
  694. words, `.' is a default argument to `update'.  This is also true for
  695. most of the CVS subcommands, not only the `update' command.
  696.    The recursive behavior of the CVS subcommands can be turned off with
  697. the `-l' option.
  698.      $ cvs update -l         # Don't update files in subdirectories
  699. File: cvs.info,  Node: Adding files,  Next: Removing files,  Prev: Recursive behavior,  Up: Top
  700. Adding files to a module
  701. ************************
  702.    To add a new file to a module, follow these steps.
  703.    * You must have a working copy of the module.  *Note Getting the
  704.      source::.
  705.    * Create the new file inside your working copy of the module.
  706.    * Use `cvs add FILENAME' to tell CVS that you want to version
  707.      control the file.
  708.    * Use `cvs commit FILENAME' to actually check in the file into the
  709.      repository.  Other developers cannot see the file until you
  710.      perform this step.
  711.    * If the file contains binary data it might be necessary to change
  712.      the default keyword substitution.  *Note Keyword substitution::.
  713.      *Note admin examples::.
  714.    You can also use the `add' command to add a new directory inside a
  715. module.
  716.    Unlike most other commands, the `add' command is not recursive.  You
  717. cannot even type `cvs add foo/bar'!  Instead, you have to
  718.      $ cd foo
  719.      $ cvs add bar
  720.    *Note add::, for a more complete description of the `add' command.
  721. File: cvs.info,  Node: Removing files,  Next: Tracking sources,  Prev: Adding files,  Up: Top
  722. Removing files from a module
  723. ****************************
  724.    Modules change.  New files are added, and old files disappear.
  725. Still, you want to be able to retrieve an exact copy of old releases of
  726. the module.
  727.    Here is what you can do to remove a file from a module, but remain
  728. able to retrieve old revisions:
  729.    * Make sure that you have not made any uncommitted modifications to
  730.      the file.  *Note Viewing differences::, for one way to do that.
  731.      You can also use the `status' or `update' command.  If you remove
  732.      the file without committing your changes, you will of course not
  733.      be able to retrieve the file as it was immediately before you
  734.      deleted it.
  735.    * Remove the file from your working copy of the module.  You can for
  736.      instance use `rm'.
  737.    * Use `cvs remove FILENAME' to tell CVS that you really want to
  738.      delete the file.
  739.    * Use `cvs commit FILENAME' to actually perform the removal of the
  740.      file from the repository.
  741.    What happens when you commit the removal of the file is that inside
  742. the source repository, it is moved into a subdirectory called `Attic'.
  743. CVS normally doesn't look in that directory when you run e.g.
  744. `checkout'.  However, if you are retrieving a certain revision via e.g.
  745. `cvs checkout -r SOME-TAG', it will look at the files inside the
  746. `Attic' and include any files that contain the specified tag.
  747. File: cvs.info,  Node: Tracking sources,  Next: Moving files,  Prev: Removing files,  Up: Top
  748. Tracking third-party sources
  749. ****************************
  750.    If you modify a program to better fit your site, you probably want
  751. to include your modifications when the next release of the program
  752. arrives.  CVS can help you with this task.
  753.    In the terminology used in CVS, the supplier of the program is
  754. called a "vendor".  The unmodified distribution from the vendor is
  755. checked in on its own branch, the "vendor branch".  CVS reserves branch
  756. 1.1.1 for this use.
  757.    When you modify the source and commit it, your revision will end up
  758. on the main trunk.  When a new release is made by the vendor, you
  759. commit it on the vendor branch and copy the modifications onto the main
  760. trunk.
  761.    Use the `import' command to create and update the vendor branch.
  762. After a successful `import' the vendor branch is made the `head'
  763. revision, so anyone that checks out a copy of the file gets that
  764. revision.  When a local modification is committed it is placed on the
  765. main trunk, and made the `head' revision.
  766. * Menu:
  767. * First import::                Importing a module for the first time
  768. * Update imports::              Updating a module with the import command
  769. File: cvs.info,  Node: First import,  Next: Update imports,  Up: Tracking sources
  770. Importing a module for the first time
  771. =====================================
  772.    Use the `import' command to check in the sources for the first time.
  773. When you use the `import' command to track third-party sources, the
  774. "vendor tag" and "release tags" are useful.  The "vendor tag" is a
  775. symbolic name for the branch (which is always 1.1.1, unless you use the
  776. `-b BRANCH' flag--*Note import options::).  The "release tags" are
  777. symbolic names for a particular release, such as `FSF_0_04'.
  778.    Suppose you use `wdiff' (a variant of `diff' that ignores changes
  779. that only involve whitespace), and are going to make private
  780. modifications that you want to be able to use even when new releases
  781. are made in the future.  You start by importing the source to your
  782. repository:
  783.      $ tar xfz wdiff-0.04.tar.gz
  784.      $ cd wdiff-0.04
  785.      $ cvs import -m "Import of FSF v. 0.04" fsf/wdiff FSF WDIFF_0_04
  786.    The vendor tag is named `FSF' in the above example, and the only
  787. release tag assigned is `WDIFF_0_04'.
  788. File: cvs.info,  Node: Update imports,  Prev: First import,  Up: Tracking sources
  789. Updating a module with the import command
  790. =========================================
  791.    When a new release of the source arrives, you import it into the
  792. repository with the same `import' command that you used to set up the
  793. repository in the first place.  The only difference is that you specify
  794. a different release tag this time.
  795.      $ tar xfz wdiff-0.05.tar.gz
  796.      $ cd wdiff-0.05
  797.      $ cvs import -m "Import of FSF v. 0.05" fsf/wdiff FSF WDIFF_0_05
  798.    For files that have not been modified locally, the newly created
  799. revision becomes the head revision.  If you have made local changes,
  800. `import' will warn you that you must merge the changes into the main
  801. trunk, and tell you to use `checkout -j' to do so.
  802.      $ cvs checkout -jFSF:yesterday -jFSF wdiff
  803. The above command will check out the latest revision of `wdiff',
  804. merging the changes made on the vendor branch `FSF' since yesterday
  805. into the working copy.  If any conflicts arise during the merge they
  806. should be resolved in the normal way (*note Conflicts example::.).
  807. Then, the modified files may be committed.
  808.    Using a date, as suggested above, assumes that you do not import
  809. more than one release of a product per day. If you do, you can always
  810. use something like this instead:
  811.      $ cvs checkout -jWDIFF_0_04 -jWDIFF_0_05 wdiff
  812. In this case, the two above commands are equivalent.
  813. File: cvs.info,  Node: Moving files,  Next: Moving directories,  Prev: Tracking sources,  Up: Top
  814. Moving and renaming files
  815. *************************
  816.    Moving files to a different directory or renaming them is not
  817. difficult, but some of the ways in which this works may be non-obvious.
  818. (Moving or renaming a directory is even harder.  *Note Moving
  819. directories::).
  820.    The examples below assume that the file OLD is renamed to NEW.
  821. * Menu:
  822. * Outside::                     The normal way to Rename
  823. * Inside::                      A tricky, alternative way
  824. * Rename by copying::           Another tricky, alternative way
  825. File: cvs.info,  Node: Outside,  Next: Inside,  Up: Moving files
  826. The Normal way to Rename
  827. ========================
  828.    The normal way to move a file is to copy OLD to NEW, and then issue
  829. the normal CVS commands to remove OLD from the repository, and add NEW
  830. to it.  (Both OLD and NEW could contain relative paths, for example
  831. `foo/bar.c').
  832.      $ mv OLD NEW
  833.      $ cvs remove OLD
  834.      $ cvs add NEW
  835.      $ cvs commit -m "Renamed OLD to NEW" OLD NEW
  836.    This is the simplest way to move a file, it is not error-prone, and
  837. it preserves the history of what was done.  Note that to access the
  838. history of the file you must specify the old or the new name, depending
  839. on what portion of the history you are accessing.  For example, `cvs
  840. log OLD' will give the log up until the time of the rename.
  841.    When NEW is committed its revision numbers will start at 1.0 again,
  842. so if that bothers you, use the `-r rev' option to commit (*note commit
  843. options::.)
  844. File: cvs.info,  Node: Inside,  Next: Rename by copying,  Prev: Outside,  Up: Moving files
  845. Moving the history file
  846. =======================
  847.    This method is more dangerous, since it involves moving files inside
  848. the repository.  Read this entire section before trying it out!
  849.      $ cd $CVSROOT/MODULE
  850.      $ mv OLD,v NEW,v
  851. Advantages:
  852.    * The log of changes is maintained intact.
  853.    * The revision numbers are not affected.
  854. Disadvantages:
  855.    * Old releases of the module cannot easily be fetched from the
  856.      repository.  (The file will show up as NEW even in revisions from
  857.      the time before it was renamed).
  858.    * There is no log information of when the file was renamed.
  859.    * Nasty things might happen if someone accesses the history file
  860.      while you are moving it.  Make sure no one else runs any of the CVS
  861.      commands while you move it.
  862. File: cvs.info,  Node: Rename by copying,  Prev: Inside,  Up: Moving files
  863. Copying the history file
  864. ========================
  865.    This way also involves direct modifications to the repository.  It
  866. is safe, but not without drawbacks.
  867.      # Copy the RCS file inside the repository
  868.      $ cd $CVSROOT/MODULE
  869.      $ cp OLD,v NEW,v
  870.      # Remove the old file
  871.      $ cd ~/MODULE
  872.      $ rm OLD
  873.      $ cvs remove OLD
  874.      $ cvs commit OLD
  875.      # Remove all tags from NEW
  876.      $ cvs update NEW
  877.      $ cvs log NEW             # Remember the tag names
  878.      $ cvs tag -d TAG1
  879.      $ cvs tag -d TAG2
  880.      ...
  881.    By removing the tags you will be able to check out old revisions of
  882. the module.
  883. Advantages:
  884.    * Checking out old revisions works correctly, as long as you use
  885.      `-rTAG' and not `-DDATE' to retrieve the revisions.
  886.    * The log of changes is maintained intact.
  887.    * The revision numbers are not affected.
  888. Disadvantages:
  889.    * You cannot easily see the history of the file across the rename.
  890.    * Unless you use the `-r rev' (*note commit options::.) flag when
  891.      NEW is committed its revision numbers will start at 1.0 again.
  892. File: cvs.info,  Node: Moving directories,  Next: Keyword substitution,  Prev: Moving files,  Up: Top
  893. Moving and renaming directories
  894. *******************************
  895.    If you want to be able to retrieve old versions of the module, you
  896. must move each file in the directory with the CVS commands.  *Note
  897. Outside::.  The old, empty directory will remain inside the repository,
  898. but it will not appear in your workspace when you check out the module
  899. in the future.
  900.    If you really want to rename or delete a directory, you can do it
  901. like this:
  902.   1. Inform everyone who has a copy of the module that the directory
  903.      will be renamed.  They should commit all their changes, and remove
  904.      their working copies of the module, before you take the steps
  905.      below.
  906.   2. Rename the directory inside the repository.
  907.           $ cd $CVSROOT/MODULE
  908.           $ mv OLD-DIR NEW-DIR
  909.   3. Fix the CVS administrative files, if necessary (for instance if
  910.      you renamed an entire module).
  911.   4. Tell everyone that they can check out the module and continue
  912.      working.
  913.    If someone had a working copy of the module the CVS commands will
  914. cease to work for him, until he removes the directory that disappeared
  915. inside the repository.
  916.    It is almost always better to move the files in the directory
  917. instead of moving the directory.  If you move the directory you are
  918. unlikely to be able to retrieve old releases correctly, since they
  919. probably depend on the name of the directories.
  920. File: cvs.info,  Node: Keyword substitution,  Next: Binary files,  Prev: Moving directories,  Up: Top
  921. Keyword substitution
  922. ********************
  923.    As long as you edit source files inside your working copy of a
  924. module you can always find out the state of your files via `cvs status'
  925. and `cvs log'.  But as soon as you export the files from your
  926. development environment it becomes harder to identify which revisions
  927. they are.
  928.    RCS uses a mechanism known as "keyword substitution" (or "keyword
  929. expansion") to help identifying the files.  Embedded strings of the form
  930. `$KEYWORD$' and `$KEYWORD:...$' in a file are replaced with strings of
  931. the form `$KEYWORD:VALUE$' whenever you obtain a new revision of the
  932. file.
  933. * Menu:
  934. * Keyword list::                RCS Keywords
  935. * Using keywords::              Using keywords
  936. * Avoiding substitution::       Avoiding substitution
  937. * Substitution modes::          Substitution modes
  938. * Log keyword::                 Problems with the $Log$ keyword.
  939. File: cvs.info,  Node: Keyword list,  Next: Using keywords,  Up: Keyword substitution
  940. RCS Keywords
  941. ============
  942.    This is a list of the keywords that RCS currently (in release
  943. 5.6.0.1) supports:
  944. `$Author$'
  945.      The login name of the user who checked in the revision.
  946. `$Date$'
  947.      The date and time (UTC) the revision was checked in.
  948. `$Header$'
  949.      A standard header containing the full pathname of the RCS file,
  950.      the revision number, the date (UTC), the author, the state, and
  951.      the locker (if locked).  Files will normally never be locked when
  952.      you use CVS.
  953. `$Id$'
  954.      Same as `$Header$', except that the RCS filename is without a path.
  955. `$Locker$'
  956.      The login name of the user who locked the revision (empty if not
  957.      locked, and thus almost always useless when you are using CVS).
  958. `$Log$'
  959.      The log message supplied during commit, preceded by a header
  960.      containing the RCS filename, the revision number, the author, and
  961.      the date (UTC).  Existing log messages are *not* replaced.
  962.      Instead, the new log message is inserted after `$Log:...$'.  Each
  963.      new line is prefixed with a "comment leader" which RCS guesses
  964.      from the file name extension.  It can be changed with `cvs admin
  965.      -c'.  *Note admin options::.  This keyword is useful for
  966.      accumulating a complete change log in a source file, but for
  967.      several reasons it can be problematic.  *Note Log keyword::.
  968. `$RCSfile$'
  969.      The name of the RCS file without a path.
  970. `$Revision$'
  971.      The revision number assigned to the revision.
  972. `$Source$'
  973.      The full pathname of the RCS file.
  974. `$State$'
  975.      The state assigned to the revision.  States can be assigned with
  976.      `cvs admin -s'--*Note admin options::.
  977. File: cvs.info,  Node: Using keywords,  Next: Avoiding substitution,  Prev: Keyword list,  Up: Keyword substitution
  978. Using keywords
  979. ==============
  980.    To include a keyword string you simply include the relevant text
  981. string, such as `$Id$', inside the file, and commit the file.  CVS will
  982. automatically expand the string as part of the commit operation.
  983.    It is common to embed `$Id$' string in the C source code.  This
  984. example shows the first few lines of a typical file, after keyword
  985. substitution has been performed:
  986.      static char *rcsid="$Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
  987.      /* The following lines will prevent `gcc' version 2.X
  988.         from issuing an "unused variable" warning. */
  989.      #if __GNUC__ == 2
  990.      #define USE(var) static void * use_##var = (&use_##var, (void *) &var)
  991.      USE (rcsid);
  992.      #endif
  993.    Even though a clever optimizing compiler could remove the unused
  994. variable `rcsid', most compilers tend to include the string in the
  995. binary.  Some compilers have a `#pragma' directive to include literal
  996. text in the binary.
  997.    The `ident' command (which is part of the RCS package) can be used
  998. to extract keywords and their values from a file.  This can be handy
  999. for text files, but it is even more useful for extracting keywords from
  1000. binary files.
  1001.      $ ident samp.c
  1002.      samp.c:
  1003.           $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
  1004.      $ gcc samp.c
  1005.      $ ident a.out
  1006.      a.out:
  1007.           $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
  1008.    SCCS is another popular revision control system.  It has a command,
  1009. `what', which is very similar to `ident' and used for the same purpose.
  1010. Many sites without RCS have SCCS.  Since `what' looks for the
  1011. character sequence `@(#)' it is easy to include keywords that are
  1012. detected by either command.  Simply prefix the RCS keyword with the
  1013. magic SCCS phrase, like this:
  1014.      static char *id="@(#) $Id: ab.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
  1015.